* GSS analysis for: 
* Class, Policy Attitudes and U.S. Presidential Voting in the Post-Industrial Era: The Importance of Issue Salience
* Franko & Witko
* Political Research Quarterly
* Date: 05/25/22


set more off


*******************************************************************************
* Presidential vote choice.
* Pooled models.
*******************************************************************************

* Create new frame to save results.
frame create dvote_diffs_gss
frame dvote_diffs_gss { 
	input 	str10 var diff ll ul str10 sample
		"egp1.5" . . . "All"
		"egp2.5" . . . "All"
		"inc5" . . . "All"
		"edu5" . . . "All"
		"white" . . . "All"
		"subclass" . . . "All"
		"egp1.5" . . . "White"
		"egp2.5" . . . "White"
		"inc5" . . . "White"
		"edu5" . . . "White"
		"subclass" . . . "White"
		"egp1.5" . . . "Nonwhite"
		"egp2.5" . . . "Nonwhite"
		"inc5" . . . "Nonwhite"
		"edu5" . . . "Nonwhite"
		"subclass" . . . "Nonwhite"
	end
}

* Create separate frame for PID results.
frame create dvote_diffs_gss_pid7
frame dvote_diffs_gss_pid7 { 
	input 	str10 var diff ll ul str10 sample
		"pid7" . . . "All"
		"pid7" . . . "White"
		"pid7" . . . "Nonwhite"
	end
}

*******************************************************************************
* Full sample.
*******************************************************************************

local varlst1 "pid7 polviews white age female south"

foreach v in b5.egp5 inc5 edu5 subclass {
	if "`v'" == "b5.egp5" {
		melogit demvote `v' `varlst1' || year: 
		estimates store dvote_egp5_gss_all
		margins , at(egp5=5) at(egp5=1) post
		lincom _b[1._at] - _b[2._at]
		frame dvote_diffs_gss { 
			replace diff = r(estimate) if var == "egp1.5" & sample == "All"
			replace ll = r(estimate) + invnorm(0.025)*r(se) if var == "egp1.5" & sample == "All"
			replace ul = r(estimate) + invnorm(0.975)*r(se) if var == "egp1.5" & sample == "All"
		}
		estimates restore dvote_egp5_gss_all
		margins , at(egp5=5) at(egp5=2) post
		lincom _b[1._at] - _b[2._at]
		frame dvote_diffs_gss {
			replace diff = r(estimate) if var == "egp2.5" & sample == "All"
			replace ll = r(estimate) + invnorm(0.025)*r(se) if var == "egp2.5" & sample == "All"
			replace ul = r(estimate) + invnorm(0.975)*r(se) if var == "egp2.5" & sample == "All"
		}
	}
	else {
		melogit demvote `v' `varlst1' || year: 
		estimates store dvote_`v'_gss_all
		margins , at((p5) `v') at((p95) `v') post
		lincom _b[1._at] - _b[2._at]
		frame dvote_diffs_gss { 
			replace diff = r(estimate) if var == "`v'" & sample == "All"
			replace ll = r(estimate) + invnorm(0.025)*r(se) if var == "`v'" & sample == "All"
			replace ul = r(estimate) + invnorm(0.975)*r(se) if var == "`v'" & sample == "All"
		}
	}
}

* Full sample, race without class covariates.
melogit demvote `varlst1' || year: 
estimates store dvote_nocls_gss_all
* Difference for white/non-white.
margins , at(white=0) at(white=1) post
lincom _b[1._at] - _b[2._at]
frame dvote_diffs_gss {
	replace diff = r(estimate) if var == "white" & sample == "All"
	replace ll = r(estimate) + invnorm(0.025)*r(se) if var == "white" & sample == "All"
	replace ul = r(estimate) + invnorm(0.975)*r(se) if var == "white" & sample == "All"
}

* Use same model for pid and policy differences.
estimates restore dvote_nocls_gss_all
margins , at((p5) pid7) at((p95) pid7) post
lincom _b[1._at] - _b[2._at]
frame dvote_diffs_gss_pid7 {
	replace diff = r(estimate) if var == "pid7" & sample == "All"
	replace ll = r(estimate) + invnorm(0.025)*r(se) if var == "pid7" & sample == "All"
	replace ul = r(estimate) + invnorm(0.975)*r(se) if var == "pid7" & sample == "All"
}


* Full sample, include all covariates.
melogit demvote b5.egp5 inc5 edu5 subclass pid7 `varlst1' || year: 
estimates store dvote_full_gss_all



*******************************************************************************
* Repeat above analysis for white only subsample.
*******************************************************************************

local varlst2 "pid7 polviews age female south"

foreach v in b5.egp5 inc5 edu5 subclass {
	if "`v'" == "b5.egp5" {
		melogit demvote `v' `varlst2' if white==1 || year:  
		estimates store dvote_egp5_gss_wo
		margins , at(egp5=5) at(egp5=1) post
		lincom _b[1._at] - _b[2._at]
		frame dvote_diffs_gss { 
			replace diff = r(estimate) if var == "egp1.5" & sample == "White"
			replace ll = r(estimate) + invnorm(0.025)*r(se) if var == "egp1.5" & sample == "White"
			replace ul = r(estimate) + invnorm(0.975)*r(se) if var == "egp1.5" & sample == "White"
		}
		estimates restore dvote_egp5_gss_wo
		margins , at(egp5=5) at(egp5=2) post
		lincom _b[1._at] - _b[2._at]
		frame dvote_diffs_gss {
			replace diff = r(estimate) if var == "egp2.5" & sample == "White"
			replace ll = r(estimate) + invnorm(0.025)*r(se) if var == "egp2.5" & sample == "White"
			replace ul = r(estimate) + invnorm(0.975)*r(se) if var == "egp2.5" & sample == "White"
		}
	}
	else {
		melogit demvote `v' `varlst2' if white==1 || year:  
		estimates store dvote_`v'_gss_wo
		margins , at((p5) `v') at((p95) `v') post
		lincom _b[1._at] - _b[2._at]
		frame dvote_diffs_gss { 
			replace diff = r(estimate) if var == "`v'" & sample == "White"
			replace ll = r(estimate) + invnorm(0.025)*r(se) if var == "`v'" & sample == "White"
			replace ul = r(estimate) + invnorm(0.975)*r(se) if var == "`v'" & sample == "White"
		}
	}
}

* White only subsample, pid without class covariates.
melogit demvote `varlst2' if white==1 || year: 
estimates store dvote_nocls_gss_wo
margins , at((p5) pid7) at((p95) pid7) post
lincom _b[1._at] - _b[2._at]
frame dvote_diffs_gss_pid7 {
	replace diff = r(estimate) if var == "pid7" & sample == "White"
	replace ll = r(estimate) + invnorm(0.025)*r(se) if var == "pid7" & sample == "White"
	replace ul = r(estimate) + invnorm(0.975)*r(se) if var == "pid7" & sample == "White"
}

* White only subsample, include all covariates.
melogit demvote b5.egp5 inc5 edu5 subclass `varlst2' if white==1 || year:  
estimates store dvote_full_gss_wo



*******************************************************************************
* Repeat above analysis for nonwhite subsample.
*******************************************************************************

local varlst2 "pid7 polviews age female south"

foreach v in b5.egp5 inc5 edu5 subclass {
	if "`v'" == "b5.egp5" {
		melogit demvote `v' `varlst2' if white==0 || year:  
		estimates store dvote_egp5_gss_nwo
		margins , at(egp5=5) at(egp5=1) post
		lincom _b[1._at] - _b[2._at]
		frame dvote_diffs_gss { 
			replace diff = r(estimate) if var == "egp1.5" & sample == "Nonwhite"
			replace ll = r(estimate) + invnorm(0.025)*r(se) if var == "egp1.5" & sample == "Nonwhite"
			replace ul = r(estimate) + invnorm(0.975)*r(se) if var == "egp1.5" & sample == "Nonwhite"
		}
		estimates restore dvote_egp5_gss_nwo
		margins , at(egp5=5) at(egp5=2) post
		lincom _b[1._at] - _b[2._at]
		frame dvote_diffs_gss {
			replace diff = r(estimate) if var == "egp2.5" & sample == "Nonwhite"
			replace ll = r(estimate) + invnorm(0.025)*r(se) if var == "egp2.5" & sample == "Nonwhite"
			replace ul = r(estimate) + invnorm(0.975)*r(se) if var == "egp2.5" & sample == "Nonwhite"
		}
	}
	else {
		melogit demvote `v' `varlst2' if white==0 || year:  
		estimates store dvote_`v'_gss_nwo
		margins , at((p5) `v') at((p95) `v') post
		lincom _b[1._at] - _b[2._at]
		frame dvote_diffs_gss { 
			replace diff = r(estimate) if var == "`v'" & sample == "Nonwhite"
			replace ll = r(estimate) + invnorm(0.025)*r(se) if var == "`v'" & sample == "Nonwhite"
			replace ul = r(estimate) + invnorm(0.975)*r(se) if var == "`v'" & sample == "Nonwhite"
		}
	}
}

* Nonwhite only subsample, pid without class covariates.
melogit demvote `varlst2' if white==0 || year: 
estimates store dvote_nocls_gss_nwo
margins , at((p5) pid7) at((p95) pid7) post
lincom _b[1._at] - _b[2._at]
frame dvote_diffs_gss_pid7 {
	replace diff = r(estimate) if var == "pid7" & sample == "Nonwhite"
	replace ll = r(estimate) + invnorm(0.025)*r(se) if var == "pid7" & sample == "Nonwhite"
	replace ul = r(estimate) + invnorm(0.975)*r(se) if var == "pid7" & sample == "Nonwhite"
}

* Nonwhite only subsample, include all covariates.
melogit demvote b5.egp5 inc5 edu5 subclass `varlst2' if white==0 || year:  
estimates store dvote_full_gss_nwo


***** Save Min/max difference results.
frame dvote_diffs_gss : save "results/dvote_diffs_gss.dta", replace
frame dvote_diffs_gss_pid7 : save "results/dvote_diffs_gss_pid7.dta", replace




*******************************************************************************
* Presidential vote choice.
* Allow social class coefficients to vary by year, then plot effects over time.
*******************************************************************************

*******************************************************************************
* Full sample.
*******************************************************************************

local varlst1 "pid7 polviews white age female south"

* EGP social class, two separate models for random coefficients.
melogit demvote egp5_1-egp5_4 `varlst1' || year: egp5_1 egp5_2 , intmethod(mc)
estimates store dvote_egp1_gss_time

melogit demvote egp5_1-egp5_4 `varlst1' || year: egp5_3 egp5_4, intmethod(mc)
estimates store dvote_egp2_gss_time

* Estimated effects: use coefficients.
* Model 1.
preserve
estimates restore dvote_egp1_gss_time

gen b_egp = .
gen se_egp = .

predict egp_re1 egp_re2 egp_re_c if e(sample), reffects reses(egp_rese1 egp_rese2 egp_rese_cons)

foreach n of numlist 1 2 {
	replace b_egp = _b[egp5_`n'] + egp_re`n' if egp5_`n' == 1
	replace se_egp = sqrt((_se[egp5_`n']^2) + (egp_rese`n'^2)) if egp5_`n' == 1
}

collapse b_egp se_egp, by(year egp5)
gen b_egp_hi = b_egp + 1.96*se_egp
gen b_egp_lo = b_egp - 1.96*se_egp

drop if b_egp == .

save "results/dvote_egp1_gss_time.dta", replace
restore

* Model 2.
preserve
estimates restore dvote_egp2_gss_time

gen b_egp = .
gen se_egp = .

predict egp_re3 egp_re4 egp_re_c if e(sample), reffects reses(egp_rese3 egp_rese4 egp_rese_cons)

foreach n of numlist 3 4 {
	replace b_egp = _b[egp5_`n'] + egp_re`n' if egp5_`n' == 1
	replace se_egp = sqrt((_se[egp5_`n']^2) + (egp_rese`n'^2)) if egp5_`n' == 1
}

collapse b_egp se_egp, by(year egp5)
gen b_egp_hi = b_egp + 1.96*se_egp
gen b_egp_lo = b_egp - 1.96*se_egp

drop if b_egp == .

save "results/dvote_egp2_gss_time.dta", replace
restore


* All other class variables.
foreach v in inc5 edu5 subclass {
	melogit demvote `v' `varlst1' || year: `v' 
	estimates store dvote_`v'_gss_time
	* Estimated effects: use coefficients.
	preserve
	predict b_re* if e(sample), reffects reses(b_rese*)

	gen b = _b[`v'] + b_re1
	gen se = sqrt((_se[`v']^2) + (b_rese1^2))

	collapse b se, by(year)
	gen b_hi = b + 1.96*se
	gen b_lo = b - 1.96*se

	drop if b == .
	gen str20 var = "`v'"

	save "results/dvote_`v'_gss_time.dta", replace
	restore
}



*******************************************************************************
* Whites only subsample.
*******************************************************************************

local varlst2 "pid7 polviews age female south"

* EGP social class, two separate models for random coefficients.
melogit demvote egp5_1-egp5_4 `varlst2' if white == 1 || year: egp5_1 egp5_2 , intmethod(mc)
estimates store dvote_egp1_gss_time_wo

melogit demvote egp5_1-egp5_4 `varlst2' if white == 1 || year: egp5_3 egp5_4, intmethod(mc)
estimates store dvote_egp2_gss_time_wo

* Estimated effects: use coefficients.
* Model 1.
preserve
estimates restore dvote_egp1_gss_time_wo

gen b_egp = .
gen se_egp = .

predict egp_re1 egp_re2 egp_re_c if e(sample), reffects reses(egp_rese1 egp_rese2 egp_rese_cons)

foreach n of numlist 1 2 {
	replace b_egp = _b[egp5_`n'] + egp_re`n' if egp5_`n' == 1
	replace se_egp = sqrt((_se[egp5_`n']^2) + (egp_rese`n'^2)) if egp5_`n' == 1
}

collapse b_egp se_egp, by(year egp5)
gen b_egp_hi = b_egp + 1.96*se_egp
gen b_egp_lo = b_egp - 1.96*se_egp

drop if b_egp == .

save "results/dvote_egp1_gss_time_wo.dta", replace
restore

* Model 2.
preserve
estimates restore dvote_egp2_gss_time_wo

gen b_egp = .
gen se_egp = .

predict egp_re3 egp_re4 egp_re_c if e(sample), reffects reses(egp_rese3 egp_rese4 egp_rese_cons)

foreach n of numlist 3 4 {
	replace b_egp = _b[egp5_`n'] + egp_re`n' if egp5_`n' == 1
	replace se_egp = sqrt((_se[egp5_`n']^2) + (egp_rese`n'^2)) if egp5_`n' == 1
}

collapse b_egp se_egp, by(year egp5)
gen b_egp_hi = b_egp + 1.96*se_egp
gen b_egp_lo = b_egp - 1.96*se_egp

drop if b_egp == .

save "results/dvote_egp2_gss_time_wo.dta", replace
restore


* All other class variables.
foreach v in inc5 edu5 subclass {
	melogit demvote `v' `varlst2' if white == 1 || year: `v'  
	estimates store dvote_`v'_gss_time_wo
	* Estimated effects: use coefficients.
	preserve
	predict b_re* if e(sample), reffects reses(b_rese*)

	gen b = _b[`v'] + b_re1
	gen se = sqrt((_se[`v']^2) + (b_rese1^2))

	collapse b se, by(year)
	gen b_hi = b + 1.96*se
	gen b_lo = b - 1.96*se

	drop if b == .
	gen str20 var = "`v'"

	save "results/dvote_`v'_gss_time_wo.dta", replace
	restore
}



